<?php
declare(strict_types=1);

namespace app\middleware;

use app\traits\ResponseTrait;
use think\facade\{Cache, Config, Request};
use Closure;

class RateLimitMiddleware
{
    use ResponseTrait;

    /**
     * 处理请求
     */
    public function handle(Request $request, Closure $next)
    {
        // 判断是否开启限流
        if (!Config::get('rate_limit.enabled', false)) {
            return $next($request);
        }

        // 获取限流配置
        $perMinute = Config::get('rate_limit.per_minute', 60);
        $perSecond = Config::get('rate_limit.per_second', 1);

        // 获取客户端标识(优先使用用户ID,其次使用IP)
        $identifier = $this->getIdentifier($request);

        // 检查每分钟限制
        $minuteKey = "rate_limit:minute:{$identifier}";
        $minuteCount = Cache::get($minuteKey, 0);
        if ($minuteCount >= $perMinute) {
            return $this->error('请求过于频繁，请稍后再试', 429);
        }

        // 检查每秒限制
        $secondKey = "rate_limit:second:{$identifier}";
        $secondCount = Cache::get($secondKey, 0);
        if ($secondCount >= $perSecond) {
            return $this->error('请求过于频繁，请稍后再试', 429);
        }

        // 更新访问计数
        Cache::inc($minuteKey);
        Cache::inc($secondKey);
        // 设置过期时间
        if ($minuteCount == 0) {
            Cache::expire($minuteKey, 60);
        }
        if ($secondCount == 0) {
            Cache::expire($secondKey, 1);
        }

        return $next($request);
    }

    /**
     * 获取客户端标识
     */
    protected function getIdentifier(Request $request): string
    {
        // 已登录用户使用用户ID
        if ($user = $request->user) {
            return "user:{$user->id}";
        }
        if ($merchant = $request->merchant) {
            return "merchant:{$merchant->id}";
        }
        if ($admin = $request->admin) {
            return "admin:{$admin->id}";
        }

        // 未登录用户使用IP
        return "ip:" . $request->ip();
    }
} 